package com.example.aidocengine.processor;

import com.example.aidocengine.common.constant.BusinessConstant;
import com.example.aidocengine.common.exception.BusinessException;
import com.example.aidocengine.common.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class WordProcessor {

    /**
     * 操作步骤数据对象
     */
    public static class OperationStepData {
        private int tableIndex;
        private int rowIndex;
        private String commandingUnit;  // 受令单位
        private String operationStep;   // 操作步骤
        private int commanderColumnIndex; // 发令人列索引
        
        // 构造函数和getter/setter
        public OperationStepData(int tableIndex, int rowIndex, String commandingUnit, String operationStep, int commanderColumnIndex) {
            this.tableIndex = tableIndex;
            this.rowIndex = rowIndex;
            this.commandingUnit = commandingUnit;
            this.operationStep = operationStep;
            this.commanderColumnIndex = commanderColumnIndex;
        }
        
        public int getTableIndex() { return tableIndex; }
        public int getRowIndex() { return rowIndex; }
        public String getCommandingUnit() { return commandingUnit; }
        public String getOperationStep() { return operationStep; }
        public int getCommanderColumnIndex() { return commanderColumnIndex; }
    }

    /**
     * 解析启动方案Word文档，提取第七部分的操作步骤数据
     */
    public List<OperationStepData> parseStartupPlanDocument(MultipartFile file) {
        List<OperationStepData> operationSteps = new ArrayList<>();
        
        try (XWPFDocument document = new XWPFDocument(file.getInputStream())) {
            log.info("开始解析Word文档：{}", file.getOriginalFilename());
            
            // 查找第七部分
            boolean foundSection7 = false;
            int currentTableIndex = 0;
            
            // 遍历文档中的段落和表格
            for (IBodyElement element : document.getBodyElements()) {
                if (element.getElementType() == BodyElementType.PARAGRAPH) {
                    XWPFParagraph paragraph = (XWPFParagraph) element;
                    String text = paragraph.getText();
                    
                    // 检查是否找到第七部分
                    if (text != null && text.contains(BusinessConstant.SECTION_SEVEN_TITLE)) {
                        foundSection7 = true;
                        log.info("找到第七部分：{}", text);
                        continue;
                    }
                    
                    // 如果已经找到第七部分，并且遇到新的章节，则停止解析
                    if (foundSection7 && text != null && 
                        (text.contains("第八部分") || text.contains("第8部分") || 
                         text.contains("八、") || text.matches(".*第[八8].*部分.*"))) {
                        log.info("遇到第八部分，结束第七部分解析");
                        break;
                    }
                }
                
                if (element.getElementType() == BodyElementType.TABLE && foundSection7) {
                    XWPFTable table = (XWPFTable) element;
                    List<OperationStepData> tableData = parseOperationTable(table, currentTableIndex);
                    operationSteps.addAll(tableData);
                    currentTableIndex++;
                }
            }
            
            if (!foundSection7) {
                throw new BusinessException(ResultCode.DOCUMENT_PARSE_ERROR.getCode(), 
                    "未找到第七部分：启动前有关厂站一、二次设备运行方式调整及状态确认");
            }
            
            log.info("Word文档解析完成，共提取{}条操作步骤数据", operationSteps.size());
            
        } catch (IOException e) {
            log.error("解析Word文档失败：", e);
            throw new BusinessException(ResultCode.DOCUMENT_PARSE_ERROR);
        }
        
        return operationSteps;
    }

    /**
     * 解析操作表格，提取受令单位和操作步骤
     */
    private List<OperationStepData> parseOperationTable(XWPFTable table, int tableIndex) {
        List<OperationStepData> tableData = new ArrayList<>();
        
        if (table.getRows().isEmpty()) {
            return tableData;
        }
        
        // 分析表格结构，查找受令单位列和操作步骤列
        Map<String, Integer> columnMapping = analyzeTableStructure(table);
        
        if (columnMapping.isEmpty()) {
            log.warn("表格{}未找到标准的受令单位和操作步骤列，跳过解析", tableIndex);
            return tableData;
        }
        
        int commandingUnitColumn = columnMapping.getOrDefault("受令单位", -1);
        int operationStepColumn = columnMapping.getOrDefault("操作步骤", -1);
        int commanderColumn = columnMapping.getOrDefault("发令人", -1);
        
        // 如果没有找到发令人列，默认使用最后一列
        if (commanderColumn == -1 && !table.getRows().isEmpty()) {
            commanderColumn = table.getRows().get(0).getTableCells().size() - 1;
        }
        
        // 从第二行开始解析数据（第一行通常是标题）
        for (int rowIndex = 1; rowIndex < table.getRows().size(); rowIndex++) {
            XWPFTableRow row = table.getRows().get(rowIndex);
            
            try {
                String commandingUnit = "";
                String operationStep = "";
                
                // 提取受令单位
                if (commandingUnitColumn >= 0 && commandingUnitColumn < row.getTableCells().size()) {
                    commandingUnit = getCellText(row.getTableCells().get(commandingUnitColumn));
                }
                
                // 提取操作步骤
                if (operationStepColumn >= 0 && operationStepColumn < row.getTableCells().size()) {
                    operationStep = getCellText(row.getTableCells().get(operationStepColumn));
                }
                
                // 只有当操作步骤不为空时才添加数据
                if (!operationStep.trim().isEmpty()) {
                    OperationStepData data = new OperationStepData(
                        tableIndex, rowIndex, 
                        commandingUnit.trim(), 
                        operationStep.trim(),
                        commanderColumn
                    );
                    tableData.add(data);
                }
                
            } catch (Exception e) {
                log.warn("解析表格{}第{}行数据失败：{}", tableIndex, rowIndex + 1, e.getMessage());
            }
        }
        
        return tableData;
    }

    /**
     * 分析表格结构，识别列映射
     */
    private Map<String, Integer> analyzeTableStructure(XWPFTable table) {
        Map<String, Integer> columnMapping = new HashMap<>();
        
        if (table.getRows().isEmpty()) {
            return columnMapping;
        }
        
        // 分析标题行
        XWPFTableRow headerRow = table.getRows().get(0);
        for (int colIndex = 0; colIndex < headerRow.getTableCells().size(); colIndex++) {
            String headerText = getCellText(headerRow.getTableCells().get(colIndex)).trim().toLowerCase();
            
            // 识别受令单位列
            if (headerText.contains("受令单位") || headerText.contains("受令")) {
                columnMapping.put("受令单位", colIndex);
            }
            
            // 识别操作步骤列
            if (headerText.contains("操作步骤") || headerText.contains("操作内容") || 
                headerText.contains("步骤") || headerText.contains("操作")) {
                columnMapping.put("操作步骤", colIndex);
            }
            
            // 识别发令人列
            if (headerText.contains("发令人") || headerText.contains("发令") || 
                headerText.contains("指挥人") || headerText.contains("负责人")) {
                columnMapping.put("发令人", colIndex);
            }
        }
        
        return columnMapping;
    }

    /**
     * 获取单元格文本内容
     */
    private String getCellText(XWPFTableCell cell) {
        if (cell == null) {
            return "";
        }
        
        StringBuilder text = new StringBuilder();
        for (XWPFParagraph paragraph : cell.getParagraphs()) {
            String paraText = paragraph.getText();
            if (paraText != null && !paraText.trim().isEmpty()) {
                if (text.length() > 0) {
                    text.append(" ");
                }
                text.append(paraText.trim());
            }
        }
        
        return text.toString();
    }
}